using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Web.Configuration;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Runtime.InteropServices;

namespace OrbitOne.SharePoint.Provision.WebParts
{
  [Guid("2bfb6e13-0747-4e23-8145-56776456db5c")]
  public abstract class GeneralWebPart : WebPart
    {
      protected SPWeb _rootWeb;
      protected string _providerType;
      protected  string _providerName;
      protected  string _siteUrl;
      protected bool _failure = false;

      public string SiteCollectionLADPConnectionString
      {
          get
          {
              if (!string.IsNullOrEmpty(_rootWeb.AllProperties[Constants.SITE_COLLECTION_LADP_KEY] as string))
                  return _rootWeb.AllProperties[Constants.SITE_COLLECTION_LADP_KEY] as string;
              else
                  throw new ConfigurationErrorsException("Active Directory Connection String is not set in Site Settings");
          }
         
      }
      public string ADRootLADPConnectionString
      {
          get
          {
              if (!string.IsNullOrEmpty(WebConfigurationManager.ConnectionStrings[Constants.ACTIVE_DIRECTORY_ROOT_LADP_KEY].ConnectionString))
                  return WebConfigurationManager.ConnectionStrings[Constants.ACTIVE_DIRECTORY_ROOT_LADP_KEY].ConnectionString;
              else
                  throw new ConfigurationErrorsException(Constants.ACTIVE_DIRECTORY_ROOT_LADP_KEY + "is not set in web.config");
          }
      }
      public string SiteCollectionOUName
      {
          get
          {
              if (!string.IsNullOrEmpty(_rootWeb.AllProperties[Constants.SITE_COLLECTION_AD_OU_NAME] as string))
              return _rootWeb.AllProperties[Constants.SITE_COLLECTION_AD_OU_NAME] as string;
              else
              throw new ConfigurationErrorsException("Organisation Unit is not set in Site Settings");

          }
      }



      public GeneralWebPart()
      {
          _rootWeb = SPContext.Current.Site.RootWeb;
      }
      protected void BuildStatus(string message, string color, HtmlTextWriter output)
        {
            if (!string.IsNullOrEmpty(message))
            {
                output.Write("<table width='100%' class='propertysheet' cellspacing='0' cellpadding='0' border='0'> <tr> <td class='ms-descriptionText'> <span id='ctl00_PlaceHolderMain_LabelMessage' class='ms-descriptionText'></span> </td> </tr> <tr> <td class='ms-error'><span id='ctl00_PlaceHolderMain_LabelErrorMessage'></span></td> </tr> <tr> <td class='ms-descriptionText'> <div id='ctl00_PlaceHolderMain_ValSummary' style='color:" + color + ";'>");
                output.Write(message);
                output.Write("</div> </td> </tr> <tr> <td><img src='/_layouts/images/blank.gif' width='10' height='1' alt='' /></td> </tr> </table>");

            }
        }
        /// <summary>
        /// Provide a line break in the html table
        /// </summary>
        /// <param name="idPrefix">ID tag for this row</param>
        /// <param name="output">HtmlTextWriter object to write final row output</param>
        /// <param name="iHeight">Height of this line break row</param>
      protected void LineBreak(string idPrefix, HtmlTextWriter output, int iHeight)
        {
            output.Write("<tr id='" + idPrefix + "_LineBreak' >");
            output.Write("<td class='ms-sectionline' height='" + iHeight.ToString() + "' colspan='2'><IMG SRC='/_layouts/images/blank.gif' width=1 height=1 alt=''></td>");
            output.Write("</tr>");
        }

      protected void LineBreak(string idPrefix, HtmlTextWriter output)
        {
            // Use a default height of 1 px
            LineBreak(idPrefix, output, 1);
        }


      protected void BuildRow(string dataName, string description, Control inputControl, HtmlTextWriter output)
        {
            string idPrefix;

            idPrefix = dataName.Trim();

            output.Write("<tr>");
            output.Write("<td class='ms-descriptiontext' valign='top'>");
            output.Write("<table border='0' cellpadding='1' cellspacing='0' width='100%'>");
            output.Write("<tr>");
            output.Write("<td class='ms-sectionheader' style='padding-top: 4px;' height='22' valign='top'>");
            output.Write("<H3 class='ms-standardheader'>");
            output.Write(dataName);
            output.Write("</H3>");

            output.Write("</td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td class='ms-descriptiontext ms-inputformdescription'>");
            output.Write(description);
            output.Write("</td>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=8 height=1 alt=''></td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=19 alt=''></td>");
            output.Write("</tr>");

            output.Write("</table>");
            output.Write("</td>");
            output.Write("<td class='ms-authoringcontrols ms-inputformcontrols' valign='top' align='left' >");
            output.Write("<table border='0' width='100%' cellspacing='0' cellpadding='0'>");
            output.Write("<tr>");

            output.Write("<td width='9px'><IMG SRC='/_layouts/images/blank.gif' width=9 height=7 alt=''></td>");

            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=7 alt=''></td>");

            output.Write("<td width='10px'><IMG SRC='/_layouts/images/blank.gif' width=10 height=1 alt=''></td>");

            output.Write("</tr>");
            output.Write("<tr>");
            output.Write("<td/>");
            output.Write("<td class='ms-authoringcontrols'>");
            output.Write("<table class='ms-authoringcontrols' border='0' width='100%' cellspacing='0' cellpadding='0'>");


            output.Write("<tr id='" + idPrefix + "_table_row'>");
            output.Write("<td class='ms-authoringcontrols' colspan='2' nowrap>");
            output.Write("<span id='" + idPrefix + "LabelText'>" + dataName + ":</span>");
            output.Write("</td>");
            output.Write("</tr>");
            output.Write("<tr id='" + idPrefix + "_tablerow2'>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=1 height=3 alt=''></td>");
            output.Write("</tr>");
            output.Write("<tr id='" + idPrefix + "_tablerow3'>");
            output.Write("<td width='11' ><IMG SRC='/_layouts/images/blank.gif' width=11 height=1 alt=''></td>");
            output.Write("<td class='ms-authoringcontrols' width='99%'>");

            inputControl.RenderControl(output);

            output.Write("</td>");
            output.Write("</tr>");

            output.Write("<tr id='" + idPrefix + "_tablerow5'>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=1 height=6 alt=''></td>");
            output.Write("</tr>");


            output.Write("</table>");
            output.Write("</td>");
            output.Write("<td width='10px'><IMG SRC='/_layouts/images/blank.gif' width=10 height=1 alt=''></td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td />");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=13 alt=''></td>");
            output.Write("<td />");
            output.Write("</tr>");

            output.Write("</table>");
            output.Write("</td>");
            output.Write("</tr>");


        }
        /// <summary>
        /// Build a table row based on the supplied control and description
        /// </summary>
        /// <param name="dataName">Title of the row</param>
        /// <param name="description">Description text to include in this row</param>
        /// <param name="inputControl">Control to place into this control</param>
        /// <param name="output">HtmlTextWriter object to write final row output</param>
        /// <param name="showRow">Determines if this row be shown by default</param>
        protected void BuildRow(string dataName, string description, Control inputControl, HtmlTextWriter output, bool showRow)
        {
            string idPrefix;
            string mainStyle = String.Empty;

            // Remove the white space from the title so we can use it as an ID
            idPrefix = Regex.Replace(dataName, "\\s+", "");

            if (!showRow)
            {
                mainStyle = "style='display:none;'";
            }

            output.Write("<tr id='" + idPrefix + "_row_main' " + mainStyle + ">");
            output.Write("<td class='ms-descriptiontext' valign='top'>");
            output.Write("<table id='" + idPrefix + "_table_main' border='0' cellpadding='1' cellspacing='0' width='100%'>");
            output.Write("<tr>");
            output.Write("<td class='ms-sectionheader' style='padding-top: 4px;' height='22' valign='top'>");
            output.Write("<H3 class='ms-standardheader'>");
            output.Write(dataName);
            output.Write("</H3>");

            output.Write("</td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td class='ms-descriptiontext ms-inputformdescription'>");
            output.Write(description);
            output.Write("</td>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=8 height=1 alt=''></td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=19 alt=''></td>");
            output.Write("</tr>");

            output.Write("</table>");
            output.Write("</td>");
            output.Write("<td class='ms-authoringcontrols ms-inputformcontrols' valign='top' align='left' >");
            output.Write("<table border='0' width='100%' cellspacing='0' cellpadding='0'>");
            output.Write("<tr>");

            output.Write("<td width='9px'><IMG SRC='/_layouts/images/blank.gif' width=9 height=7 alt=''></td>");

            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=7 alt=''></td>");

            output.Write("<td width='10px'><IMG SRC='/_layouts/images/blank.gif' width=10 height=1 alt=''></td>");

            output.Write("</tr>");
            output.Write("<tr>");
            output.Write("<td/>");
            output.Write("<td class='ms-authoringcontrols'>");
            output.Write("<table class='ms-authoringcontrols' border='0' width='100%' cellspacing='0' cellpadding='0'>");


            output.Write("<tr id='" + idPrefix + "_table_row'>");
            output.Write("<td class='ms-authoringcontrols' colspan='2' nowrap>");
            output.Write("<span id='" + idPrefix + "LabelText'>" + dataName + ":</span>");
            output.Write("</td>");
            output.Write("</tr>");
            output.Write("<tr id='" + idPrefix + "_tablerow2'>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=1 height=3 alt=''></td>");
            output.Write("</tr>");
            output.Write("<tr id='" + idPrefix + "_tablerow3'>");
            output.Write("<td width='11' ><IMG SRC='/_layouts/images/blank.gif' width=11 height=1 alt=''></td>");
            output.Write("<td class='ms-authoringcontrols' width='99%'>");

            inputControl.RenderControl(output);

            output.Write("</td>");
            output.Write("</tr>");

            output.Write("<tr id='" + idPrefix + "_tablerow5'>");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=1 height=6 alt=''></td>");
            output.Write("</tr>");


            output.Write("</table>");
            output.Write("</td>");
            output.Write("<td width='10px'><IMG SRC='/_layouts/images/blank.gif' width=10 height=1 alt=''></td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td />");
            output.Write("<td><IMG SRC='/_layouts/images/blank.gif' width=150 height=13 alt=''></td>");
            output.Write("<td />");
            output.Write("</tr>");

            output.Write("</table>");
            output.Write("</td>");
            output.Write("</tr>");

        }
      protected void BuildButton(Control btnControl, HtmlTextWriter output)
        {
            output.Write("<tr>");
            output.Write("<td height='10px' class='ms-descriptiontext' colspan='2'><IMG SRC='/_layouts/images/blank.gif' width=1 height=10 alt=''></td>");
            output.Write("</tr>");
            output.Write("<tr>");
            output.Write("<td colspan='2'>");
            output.Write("<table cellpadding='0' cellspacing='0' width='100%'>");
            output.Write("<colgroup>");
            output.Write("<col width='99%'>");
            output.Write("<col width='1%'>");
            output.Write("</colgroup>");
            output.Write("<tr>");
            output.Write("<td>");
            output.Write("&nbsp;</td>");
            output.Write("<td nowrap>");

            btnControl.RenderControl(output);

            output.Write("</td>");
            output.Write("</tr>");
            output.Write("</table>");
            output.Write("</td>");
            output.Write("</tr>");

            output.Write("<tr>");
            output.Write("<td height='40' class='ms-descriptiontext' colspan='2'><IMG SRC='/_layouts/images/blank.gif' width=1 height=40 alt=''></td>");
            output.Write("</tr>");

        }


        /// <summary>
        /// Determine if this is using an AD provider or a SQL provider
        /// </summary>
        protected void DetermineProviderType()
        {
            string connStrValue = String.Empty;
            string connStrName = String.Empty;
            string tempType = String.Empty;
            NameValueCollection configData;

            try
            {


                // Get the provider name from the current Membership object
                _providerName = Membership.Provider.Name;

                // Get the Membership section in the web.config file
                MembershipSection configSection = (MembershipSection)Context.GetSection("system.web/membership");

                // Get the parameters for this provider
                configData = configSection.Providers[_providerName].Parameters;

                // Get the name of the connection string in use by this provider
                connStrName = configData["connectionStringName"];

                // Get the value of the connection string
                connStrValue = WebConfigurationManager.ConnectionStrings[connStrName].ConnectionString;

                if (connStrValue.Contains("LDAP://"))
                {
                    // Assume this is an LDAP string pointing to Active Directory
                    tempType = "AD";

                    // Get the impersonation user and password information

                }
                else
                {
                    tempType = "SQL";
                }

                AuthenticationSection authenticationSection =
                        (AuthenticationSection)Context.GetSection("system.web/authentication");
                if (authenticationSection.Mode == AuthenticationMode.Windows)
                {
                    _providerName = Helper.GetDomainNameFromIdentity(Context.User.Identity.Name);
                    tempType = "WindowsIntergrated";
                }
            }
            catch
            {
                tempType = "Unknown";
            }

            // Set the global parameter for provider type
            _providerType = tempType;

        }

        /// <summary>
        /// Return the Application Name (if AD) or OU Name (if SQL)
        /// </summary>
        /// <returns>Name of the group for this and other sites</returns>
        protected string GetGroupName()
        {
            string groupName = String.Empty;

            if (_providerType == "SQL")
            {
                // Get the Application Name used with the custom SQL provider
                groupName = Membership.Provider.ApplicationName;
            }
            if (_providerType == "WindowsIntergrated" || _providerType == "AD")
            {
                groupName = SiteCollectionOUName;

            }

            return groupName;
        }

        /// <summary>
        /// Determine if this is using an AD provider or a SQL provider
        /// </summary>

        /// <summary>
        /// Checks all of the password fields for rules compliance
        /// </summary>
        /// <param name="password">Password to check for compliance</param>
        /// <param name="verifyPassword">Verify password to check for match</param>
        protected void CheckPassword(string password, string verifyPassword)
        {
            int MinRequiredPasswordLength = 0;
            int MinRequiredNonAlphanumericCharacters = 0;
            int count = 0;

            // Load the values from the provider
            if (_providerType != "WindowsIntergrated")
            {
                MinRequiredNonAlphanumericCharacters = Membership.Provider.MinRequiredNonAlphanumericCharacters;
                MinRequiredPasswordLength = Membership.Provider.MinRequiredPasswordLength;
            }

            if (!String.IsNullOrEmpty(verifyPassword))
            {
                // Make sure the user has verified this password
                if (password != verifyPassword)
                {
                    // Throw an exception if this does not meet this policy requirement
                    throw new Exception("The passwords do not match.");
                }
            }

            // Make sure the new password meets the min length requirement
            if (password.Length < MinRequiredPasswordLength)
            {
                throw new Exception("The password must be at least " + MinRequiredPasswordLength.ToString() + " characters.");
            }

            // Determine how many non-alphanumeric characters are in this password
            for (int i = 0; i < password.Length; i++)
            {
                if (!char.IsLetterOrDigit(password, i))
                {
                    count++;
                }
            }
            // Throw an exception if this does not meet this policy requirement
            if (count < MinRequiredNonAlphanumericCharacters)
            {
                throw new Exception("The password must have at least " + MinRequiredNonAlphanumericCharacters.ToString() + " non-alphanumeric characters.");
            }
        }
        /// <summary>
        /// Generates a random password string.
        /// </summary>
        /// <returns></returns>
        public static string GeneratePassword()
        {
            string newPassword = String.Empty;

            int minimumRequiredPasswordLength;
            
           

            Int32.TryParse(ConfigurationManager.AppSettings["autoGeneratedPasswordLength"],
                           out minimumRequiredPasswordLength);
           
            try
            {
                // Call into the Membership provider to generate a password

                newPassword = Membership.GeneratePassword(minimumRequiredPasswordLength==0?7:minimumRequiredPasswordLength, 0);

            }
            catch (Exception exc)
            {
                throw;
            }



            return FilterOutInvalidPasswordCharacters(newPassword);
        }


      private static string FilterOutInvalidPasswordCharacters(string password)
      {
           string validPasswordCharacters = ConfigurationManager.AppSettings["validPasswordCharacters"];
          foreach (char c in password)
          {
              if(!validPasswordCharacters.Contains(c.ToString()))
              {
                 password =  password.Replace(c, GetRandomCharInString(validPasswordCharacters));
              }
          }
          return password;
      }
      
      private static char GetRandomCharInString(string str)
      {
          Random randNum = new Random();
          int randomIndex = randNum.Next(str.Length);
          return str[randomIndex];
      }
    }
}
